/*
** server.c -- a stream socket server demo
*/

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/wait.h>

#define MYPORT 3477    /* the port users will be connecting to */
#define BACKLOG 10     /* how many pending connections queue will hold */
#define MAXDATASIZE 100

main()
{
  int sockfd, new_fd, numbytes;  /* listen on sock_fd, new connection on new_fd */
  struct sockaddr_in my_addr;    /* my address information */
  struct sockaddr_in their_addr; /* connector's address information */
  int sin_size, numreads, numchar, x=0, yes=1;
  char buf[MAXDATASIZE];
  FILE *rsock, *wsock;

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
    perror("socket");
    exit(1);
  }
  
  my_addr.sin_family = AF_INET;         /* host byte order */
  my_addr.sin_port = htons(MYPORT);     /* short, network byte order */
  my_addr.sin_addr.s_addr = INADDR_ANY; /* automatically fill with my IP */
  bzero(&(my_addr.sin_zero), 8);        /* zero the rest of the struct */

  if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
    perror("bind");
    exit(1);
  }

  if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
    perror("setsockopt");
    exit(1);
  }

  if (listen(sockfd, BACKLOG) == -1) {
    perror("listen");
    exit(1);
  }

  while(1) {  /* main accept() loop */
    sin_size = sizeof(struct sockaddr_in);
 
    if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
      perror("accept");
      continue;
    }

    if (!fork()){ 
      numreads = 0;
      numchar = 0;

      rsock = fdopen(new_fd, "r");
      wsock = fdopen(new_fd, "w");
	
      while (fgets(buf, MAXDATASIZE, rsock) != NULL){
	fflush(rsock);
	numreads++;
	numchar += strlen(buf);
	if (fputs(buf, wsock) == EOF){
	  perror("fputs");
	  exit(1);
	}
	fflush(wsock);
      }	 

      fprintf (stderr, "Número de linhas lidas: %d\nNúmero de caracteres lidos: %d\n",
	       numreads, numchar);
      close(new_fd);
      
      exit(1);
    }
   
    close(new_fd);
  }
}


